![]() |
Java Database Programming with JDBC
by Pratik Patel Coriolis, The Coriolis Group ISBN: 1576100561 Pub Date: 10/01/96 |
Previous | Table of Contents | Next |
Now that we have the server code, lets look at the client class, which is shown in Listing 11.2. This client class is not self-standing; well need an applet to call this class and make use of the methods we define in it. The code for a sample applet that calls this client class is shown in Listing 11.3. Note that the client is specially coded to communicate with the application server in Listing 11.1, and that it does not require the Web browser it is run on to have the JDBC API classes. For our simple example, we dont need to implement all of the functionality that is demanded of a JDBC driver, so I didnt write one; a JDBC driver that can talk to our application server would not be difficult to write at this point, however, because we have a simple command set and simple functionality. Figure 11.3 shows the client applet in Listing 11.3, which uses the Dbclient class.
Figure 11.3 Sample applet that uses our client.
Listing 11.2 Client class.
import java.io.*; import java.net.*; import java.applet.*; public class DBClient { public Socket socket; public PrintStream out; public String Name; public Reader reader; public DBClient (String ServerName, int ServerPort) { try { socket = new Socket(ServerName, ServerPort); // We put the reading of the inputStream from the application // server in its own thread, Reader. reader = new Reader(this); out = new PrintStream(socket.getOutputStream()); } catch (IOException e) {System.err.println(e);} } public String ProcessCommand(String InLine) { System.out.println("FROM DBCLIENT:"+InLine); out.println(InLine); out.flush(); // tell the reader we've sent some data/command synchronized(reader){reader.notify();reader.notifyOn=false;} while(true) { // We have to wait until the Reader has finished reading, so we set // this notifyOn flag in the reader when it has finished reading. if (reader.notifyOn) {break;} } // Return the results of the command/query return(reader.getResult()); } } class Reader extends Thread { // This class reads data in from the application server protected DBClient client; public String Result="original"; public boolean notifyOn=true; public Reader(DBClient c) { super("DBclient Reader"); this.client = c; this.start(); } public synchronized void run() { String line=""; DataInputStream in=null; try { in = new DataInputStream(client.socket.getInputStream()); while(true) { // We start reading when we are notified from the main thread // and we stop when we have finished reading the stream for // this command/query. try {if (notifyOn) {this.wait(); notifyOn=false; Result="";}} catch (InterruptedException e){ System.out.println("Caught an Interrupted Exception"); } // Prevent simultaneous access line = in.readLine(); if (line.equalsIgnoreCase("DONE")) { notifyOn=true; } else { if (line == null) { System.out.println("Server closed connection."); break; } // if NOT null else {Result+=line+"\n";} System.out.println("Read from server: "+Result); } // if NOT done.. } //while loop } catch (IOException e) {System.out.println("Reader: " + e);} finally { try {if (in != null) in.close();} catch (IOException e) { System.exit(0); } } } public String getResult() { return (Result); } }
The client class needs to be instantiated in a Java program, and the connection needs to be started before any queries can be made. If you remember our Interactive Query Applet from Chapter 4, this sample applet will certainly look familiar to you.
Listing 11.3 Applet to call our client class.
import java.net.URL; import java.awt.*; import java.applet.Applet; import DBClient; public class IQ extends java.applet.Applet { Button ConnectBtn = new Button("Connect to Database"); protected DBClient DataConnection; TextField QueryField = new TextField(40); TextArea OutputField = new TextArea(10,75); public void init() { QueryField.setEditable(true); OutputField.setEditable(false); DataConnection = new DBClient(getDocumentBase().getHost(), 6001); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints Con = new GridBagConstraints(); setLayout(gridbag); setFont(new Font("Helvetica", Font.PLAIN, 12)); setBackground(Color.gray); Con.weightx=1.0; Con.weighty=0.0; Con.anchor = GridBagConstraints.CENTER; Con.fill = GridBagConstraints.NONE; Con.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(ConnectBtn, Con); add(ConnectBtn); add(new Label("SQL Query")); gridbag.setConstraints(QueryField, Con); add(QueryField); Label result_label = new Label("Result"); result_label.setFont(new Font("Helvetica", Font.PLAIN, 16)); result_label.setForeground(Color.blue); gridbag.setConstraints(result_label, Con); Con.weighty=1.0; add(result_label); gridbag.setConstraints(OutputField, Con); OutputField.setForeground(Color.white); OutputField.setBackground(Color.black); add(OutputField); show(); } //init public boolean handleEvent(Event evt) { if ((evt.target == QueryField) & (evt.id == Event.KEY_PRESS)) {char c=(char)evt.key; if (c == '\n') { // When a user enters q query and hits "return," we send the // query to be processed and get the results to show in the // OutputField. DataConnection.ProcessCommand("S"); OutputField.setText(DataConnection.ProcessCommand(QueryField.getText())); return true; } } if ((evt.target == ConnectBtn) & (evt.id == Event.ACTION_EVENT)) { // This is the first command the application server expects, // connect to the data source. OutputField.setText(DataConnection.ProcessCommand("L")); return true; } return false; } // handleEvent() }
Previous | Table of Contents | Next |